
<!DOCTYPE html>
<html lang="zh-CN" class="loading">
<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>OpenGL学习之路之三角形绘制 - 浪子之心</title>
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
    <meta name="google" content="notranslate" />
    <meta name="keywords" content="Blog,"> 
    <meta name="description" content="MrChen Bolg,先从几何阶段取出顶点转换成vbo转到vao如果有重复顶点可以转到EBoopenGL是一个状态机只能运行context的状态只能放一个vao状态机中必须要一个vao
VAO123   unsigned,"> 
    <meta name="author" content="Jack Chen"> 
    <link rel="alternative" href="atom.xml" title="浪子之心" type="application/atom+xml"> 
    <link rel="icon" href="/blog/img/favicon.png"> 
    
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.css">

    
<link rel="stylesheet" href="/blog/css/diaspora.css">

<meta name="generator" content="Hexo 5.4.1"><link rel="stylesheet" href="/blog/css/prism.css" type="text/css"></head>

<body class="loading">
    <span id="config-title" style="display:none">浪子之心</span>
    <div id="loader"></div>
    <div id="single">
    <div id="top" style="display: block;">
    <div class="bar" style="width: 0;"></div>
    <a class="iconfont icon-home image-icon" href="javascript:;" data-url="https://mrchenlearnspace.github.io/blog"></a>
    <div title="播放/暂停" class="iconfont icon-play"></div>
    <h3 class="subtitle">OpenGL学习之路之三角形绘制</h3>
    <div class="social">
        <div>
            <div class="share">
                <a title="获取二维码" class="iconfont icon-scan" href="javascript:;"></a>
            </div>
            <div id="qr"></div>
        </div>
    </div>
    <div class="scrollbar"></div>
</div>

    <div class="section">
        <div class="article">
    <div class='main'>
        <h1 class="title">OpenGL学习之路之三角形绘制</h1>
        <div class="stuff">
            <span>十一月 02, 2021</span>
            
  <ul class="post-tags-list" itemprop="keywords"><li class="post-tags-list-item"><a class="post-tags-list-link" href="/blog/tags/OpenGL/" rel="tag">OpenGL</a></li></ul>


        </div>
        <div class="content markdown">
            <p><strong>先从几何阶段取出顶点转换成vbo转到vao如果有重复顶点可以转到EBo<br>openGL是一个状态机只能运行context的状态只能放一个vao<br>状态机中必须要一个vao</strong></p>
<h3 id="VAO"><a href="#VAO" class="headerlink" title="VAO"></a>VAO</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">   <span class="type">unsigned</span> <span class="type">int</span> VAO;</span><br><span class="line"><span class="built_in">glGenVertexArrays</span>(<span class="number">1</span>, &amp;VAO);</span><br><span class="line"><span class="built_in">glBindVertexArray</span>(VAO);<span class="comment">//注意</span></span><br></pre></td></tr></table></figure>
<h3 id="VBO"><a href="#VBO" class="headerlink" title="VBO"></a>VBO</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">unsigned</span> <span class="type">int</span> VBO;</span><br><span class="line"><span class="built_in">glGenBuffers</span>(<span class="number">1</span>, &amp;VBO);<span class="comment">//一个缓冲ID生成一个VBO对象建立顶点缓冲对象</span></span><br><span class="line"><span class="built_in">glBindBuffer</span>(GL_ARRAY_BUFFER, VBO);<span class="comment">//新创建的缓冲绑定到GL_ARRAY_BUFFER目标</span></span><br><span class="line"><span class="built_in">glBufferData</span>(GL_ARRAY_BUFFER, <span class="built_in">sizeof</span>(vertices), vertices, GL_STATIC_DRAW);<span class="comment">//它会把之前定义的顶点数据复制到缓冲的内存中</span></span><br></pre></td></tr></table></figure>
<p>一定要绑定顶点数组</p>
<h3 id="shader"><a href="#shader" class="headerlink" title="shader"></a>shader</h3><p>顶点着色器</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">   <span class="type">unsigned</span> <span class="type">int</span> vertexShader;</span><br><span class="line">vertexShader = <span class="built_in">glCreateShader</span>(GL_VERTEX_SHADER);<span class="comment">//由于我们正在创建一个顶点着色器，传递的参数是GL_VERTEX_SHADER</span></span><br><span class="line"><span class="built_in">glShaderSource</span>(vertexShader, <span class="number">1</span>, &amp;vertexShaderSource, <span class="literal">NULL</span>);<span class="comment">//这个着色器源码附加到着色器对象上</span></span><br><span class="line"><span class="built_in">glCompileShader</span>(vertexShader);<span class="comment">//编译着色器</span></span><br></pre></td></tr></table></figure>
<p>片段着色器</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">unsigned</span> <span class="type">int</span> fragmentShader;</span><br><span class="line">fragmentShader = <span class="built_in">glCreateShader</span>(GL_FRAGMENT_SHADER);</span><br><span class="line"><span class="built_in">glShaderSource</span>(fragmentShader, <span class="number">1</span>, &amp;fragmentShaderSource, <span class="literal">NULL</span>);</span><br><span class="line"><span class="built_in">glCompileShader</span>(fragmentShader);</span><br></pre></td></tr></table></figure>
<p>着色器程序</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">   <span class="type">unsigned</span> <span class="type">int</span> shaderProgram;</span><br><span class="line">shaderProgram = <span class="built_in">glCreateProgram</span>();<span class="comment">//建立着色器程序对象</span></span><br><span class="line"><span class="built_in">glAttachShader</span>(shaderProgram, vertexShader);</span><br><span class="line"><span class="built_in">glAttachShader</span>(shaderProgram, fragmentShader);<span class="comment">//附加着色器</span></span><br><span class="line"><span class="built_in">glLinkProgram</span>(shaderProgram);<span class="comment">//连接着色器</span></span><br><span class="line"><span class="built_in">glDeleteShader</span>(vertexShader);<span class="comment">//着色器对象链接到程序对象以后，记得删除着色器对象，我们不再需要它们了</span></span><br><span class="line"><span class="built_in">glDeleteShader</span>(fragmentShader);</span><br></pre></td></tr></table></figure>
<p>序列化数据，可以得到数据的属性，是uv图片还是顶点信息</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">glVertexAttribPointer</span>(<span class="number">0</span>, <span class="number">3</span>, GL_FLOAT, GL_FALSE, <span class="number">3</span> * <span class="built_in">sizeof</span>(<span class="type">float</span>), (<span class="type">void</span>*)<span class="number">0</span>);</span><br><span class="line"><span class="built_in">glEnableVertexAttribArray</span>(<span class="number">0</span>);</span><br></pre></td></tr></table></figure>


<p>EBO的使用<br>需要加人索引<br>unsigned int indices[] &#x3D; { &#x2F;&#x2F; 注意索引从0开始!<br>    0, 1, 3, &#x2F;&#x2F; 第一个三角形<br>    1, 2, 3  &#x2F;&#x2F; 第二个三角形<br>};来确定三角形<br>放发与VBO类似当有点点区别<br>绑定缓存时GL_ELEMENT_ARRAY_BUFFER，</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">glBindBuffer</span>(GL_ELEMENT_ARRAY_BUFFER, EBO);</span><br></pre></td></tr></table></figure>
<p>绑定缓存数据的是索引值</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">glBufferData</span>(GL_ELEMENT_ARRAY_BUFFER, <span class="built_in">sizeof</span>(indices), indices, GL_STATIC_DRAW);</span><br></pre></td></tr></table></figure>
<p>在具体绘画过程中</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">glDrawElements</span>(GL_TRIANGLES, <span class="number">6</span>, GL_UNSIGNED_INT, <span class="number">0</span>);</span><br><span class="line">    <span class="built_in">glBindVertexArray</span>(<span class="number">0</span>);<span class="comment">//这是vao没有的</span></span><br></pre></td></tr></table></figure>
<p>用的函数也是和VAO绘制有区别的<br>三角形不用EBO的代码</p>
<p>四边形代码如下</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">define</span> GLEW_STATIC</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;GL/glew.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;GLFW/glfw3.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">CheckCompileShaderSuccess</span><span class="params">(<span class="type">unsigned</span> <span class="type">int</span> vertexShader)</span></span>;<span class="comment">//检查着色器是否编译成功</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">CheckLinkShaderSuccess</span><span class="params">(<span class="type">unsigned</span> <span class="type">int</span> shaderProgram)</span></span>;</span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">framebuffer_size_callback</span><span class="params">(GLFWwindow* window, <span class="type">int</span> width, <span class="type">int</span> height)</span></span>;</span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">processInput</span><span class="params">(GLFWwindow* window)</span></span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//float vertices[] = &#123;</span></span><br><span class="line"><span class="comment">//  -0.5f, -0.5f, 0.0f,</span></span><br><span class="line"><span class="comment">//   0.5f, -0.5f, 0.0f,</span></span><br><span class="line"><span class="comment">//   0.0f,  0.5f, 0.0f</span></span><br><span class="line"><span class="comment">//&#125;;</span></span><br><span class="line"><span class="type">float</span> vertices[] = &#123;</span><br><span class="line">  <span class="number">0.5f</span>, <span class="number">0.5f</span>, <span class="number">0.0f</span>,   <span class="comment">// 右上角</span></span><br><span class="line">  <span class="number">0.5f</span>, <span class="number">-0.5f</span>, <span class="number">0.0f</span>,  <span class="comment">// 右下角</span></span><br><span class="line">  <span class="number">-0.5f</span>, <span class="number">-0.5f</span>, <span class="number">0.0f</span>, <span class="comment">// 左下角</span></span><br><span class="line">  <span class="number">-0.5f</span>, <span class="number">0.5f</span>, <span class="number">0.0f</span>   <span class="comment">// 左上角</span></span><br><span class="line">&#125;;</span><br><span class="line"><span class="type">unsigned</span> <span class="type">int</span> indices[] = &#123; <span class="comment">// 注意索引从0开始! </span></span><br><span class="line">  <span class="number">0</span>, <span class="number">1</span>, <span class="number">3</span>, <span class="comment">// 第一个三角形</span></span><br><span class="line">  <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>  <span class="comment">// 第二个三角形</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="type">const</span> <span class="type">char</span>* vertexShaderSource =</span><br><span class="line"><span class="string">&quot;#version 330 core\n&quot;</span></span><br><span class="line"><span class="string">&quot;layout(location = 0) in vec3 aPos;\n&quot;</span></span><br><span class="line"><span class="string">&quot;void main()&#123;\n&quot;</span></span><br><span class="line"><span class="string">&quot;  gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);&#125;\n&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="type">const</span> <span class="type">char</span>* fragmentShaderSource =</span><br><span class="line"><span class="string">&quot;#version 330 core\n&quot;</span></span><br><span class="line"><span class="string">&quot;out vec4 FragColor;\n;&quot;</span></span><br><span class="line"><span class="string">&quot;void main()&#123;\n&quot;</span></span><br><span class="line"><span class="string">&quot;    FragColor=vec4(1.0f,0.5f,0.2f,1.0f);&#125;\n&quot;</span>;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">  <span class="built_in">glfwInit</span>();</span><br><span class="line">  <span class="built_in">glfwWindowHint</span>(GLFW_CONTEXT_VERSION_MAJOR, <span class="number">3</span>);</span><br><span class="line">  <span class="built_in">glfwWindowHint</span>(GLFW_CONTEXT_VERSION_MINOR, <span class="number">3</span>);</span><br><span class="line">  <span class="built_in">glfwWindowHint</span>(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);</span><br><span class="line">  <span class="comment">//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);MacOSX系统加上这一句</span></span><br><span class="line">  <span class="comment">//以上是初始化Glfw，说明我们要使用的OPENGL版本是3.3，我们同样明确告诉GLFW我们使用的是核心模式(Core-profile)。明确告诉GLFW我们需要使用核心模式意味着我们只能使用OpenGL功能的一个子集。</span></span><br><span class="line"></span><br><span class="line">  GLFWwindow* window = <span class="built_in">glfwCreateWindow</span>(<span class="number">800</span>, <span class="number">600</span>, <span class="string">&quot;LearnOPENGL&quot;</span>, <span class="literal">NULL</span>, <span class="literal">NULL</span>);<span class="comment">//前两个参数代表生成窗口大小</span></span><br><span class="line">  <span class="keyword">if</span> (window == <span class="literal">NULL</span>)</span><br><span class="line">  &#123;</span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;GLFW窗口初始化失败&quot;</span> &lt;&lt; std::endl;</span><br><span class="line">    <span class="built_in">glfwTerminate</span>();<span class="comment">//程序终止函数</span></span><br><span class="line">    <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="built_in">glfwMakeContextCurrent</span>(window);</span><br><span class="line">  <span class="comment">//GLFW初始化</span></span><br><span class="line">  glewExperimental = GL_TRUE;</span><br><span class="line">  <span class="keyword">if</span> (<span class="built_in">glewInit</span>() != GLEW_OK)</span><br><span class="line">  &#123;</span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;GLEW初始化失败&quot;</span> &lt;&lt; std::endl;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">//Glew的初始化</span></span><br><span class="line">  <span class="built_in">glViewport</span>(<span class="number">0</span>, <span class="number">0</span>, <span class="number">800</span>, <span class="number">600</span>);<span class="comment">//渲染窗口大小</span></span><br><span class="line">  <span class="built_in">glfwSetFramebufferSizeCallback</span>(window, framebuffer_size_callback);<span class="comment">//注册函数</span></span><br><span class="line">  </span><br><span class="line">  <span class="type">unsigned</span> <span class="type">int</span> VAO;</span><br><span class="line">  <span class="built_in">glGenVertexArrays</span>(<span class="number">1</span>, &amp;VAO);</span><br><span class="line">  <span class="built_in">glBindVertexArray</span>(VAO);</span><br><span class="line">  <span class="comment">//顶点数据绑定</span></span><br><span class="line">  <span class="type">unsigned</span> <span class="type">int</span> VBO;</span><br><span class="line">  <span class="built_in">glGenBuffers</span>(<span class="number">1</span>, &amp;VBO);<span class="comment">//一个缓冲ID生成一个VBO对象建立顶点缓冲对象</span></span><br><span class="line">  <span class="built_in">glBindBuffer</span>(GL_ARRAY_BUFFER, VBO);<span class="comment">//新创建的缓冲绑定到GL_ARRAY_BUFFER目标</span></span><br><span class="line">  <span class="built_in">glBufferData</span>(GL_ARRAY_BUFFER, <span class="built_in">sizeof</span>(vertices), vertices, GL_STATIC_DRAW);<span class="comment">//它会把之前定义的顶点数据复制到缓冲的内存中</span></span><br><span class="line">  </span><br><span class="line">  <span class="type">unsigned</span> EBO;</span><br><span class="line">  <span class="built_in">glGenBuffers</span>(<span class="number">1</span>, &amp;EBO);</span><br><span class="line">  <span class="built_in">glBindBuffer</span>(GL_ELEMENT_ARRAY_BUFFER, EBO);</span><br><span class="line">  <span class="built_in">glBufferData</span>(GL_ELEMENT_ARRAY_BUFFER, <span class="built_in">sizeof</span>(indices), indices, GL_STATIC_DRAW);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">  <span class="comment">//顶点着色器</span></span><br><span class="line"></span><br><span class="line">  </span><br><span class="line">  </span><br><span class="line">  <span class="type">unsigned</span> <span class="type">int</span> vertexShader;</span><br><span class="line">  vertexShader = <span class="built_in">glCreateShader</span>(GL_VERTEX_SHADER);<span class="comment">//由于我们正在创建一个顶点着色器，传递的参数是GL_VERTEX_SHADER</span></span><br><span class="line">  <span class="built_in">glShaderSource</span>(vertexShader, <span class="number">1</span>, &amp;vertexShaderSource, <span class="literal">NULL</span>);<span class="comment">//这个着色器源码附加到着色器对象上</span></span><br><span class="line">  <span class="built_in">glCompileShader</span>(vertexShader);<span class="comment">//编译着色器</span></span><br><span class="line">  <span class="built_in">CheckCompileShaderSuccess</span>(vertexShader);</span><br><span class="line"></span><br><span class="line">  <span class="comment">//片段着色器</span></span><br><span class="line">  <span class="type">unsigned</span> <span class="type">int</span> fragmentShader;</span><br><span class="line">  fragmentShader = <span class="built_in">glCreateShader</span>(GL_FRAGMENT_SHADER);</span><br><span class="line">  <span class="built_in">glShaderSource</span>(fragmentShader, <span class="number">1</span>, &amp;fragmentShaderSource, <span class="literal">NULL</span>);</span><br><span class="line">  <span class="built_in">glCompileShader</span>(fragmentShader);</span><br><span class="line"></span><br><span class="line">  <span class="comment">//着色器程序</span></span><br><span class="line">  <span class="type">unsigned</span> <span class="type">int</span> shaderProgram;</span><br><span class="line">  shaderProgram = <span class="built_in">glCreateProgram</span>();<span class="comment">//建立着色器程序对象</span></span><br><span class="line">  <span class="built_in">glAttachShader</span>(shaderProgram, vertexShader);</span><br><span class="line">  <span class="built_in">glAttachShader</span>(shaderProgram, fragmentShader);<span class="comment">//附加着色器</span></span><br><span class="line">  <span class="built_in">glLinkProgram</span>(shaderProgram);<span class="comment">//连接着色器</span></span><br><span class="line">  <span class="built_in">CheckLinkShaderSuccess</span>(shaderProgram);</span><br><span class="line">  <span class="built_in">glDeleteShader</span>(vertexShader);<span class="comment">//着色器对象链接到程序对象以后，记得删除着色器对象，我们不再需要它们了</span></span><br><span class="line">  <span class="built_in">glDeleteShader</span>(fragmentShader);</span><br><span class="line">  <span class="built_in">glVertexAttribPointer</span>(<span class="number">0</span>, <span class="number">3</span>, GL_FLOAT, GL_FALSE, <span class="number">3</span> * <span class="built_in">sizeof</span>(<span class="type">float</span>), (<span class="type">void</span>*)<span class="number">0</span>);</span><br><span class="line">  <span class="built_in">glEnableVertexAttribArray</span>(<span class="number">0</span>);</span><br><span class="line">  <span class="keyword">while</span> (!<span class="built_in">glfwWindowShouldClose</span>(window))</span><br><span class="line">  &#123;</span><br><span class="line">    <span class="comment">//输入</span></span><br><span class="line">    <span class="built_in">processInput</span>(window);</span><br><span class="line"></span><br><span class="line">    <span class="comment">//渲染指令</span></span><br><span class="line">    <span class="built_in">glClearColor</span>(<span class="number">0.2f</span>, <span class="number">0.3f</span>, <span class="number">0.3f</span>, <span class="number">1.0f</span>);<span class="comment">//来设置清空屏幕所用的颜色,表示清除板的颜色</span></span><br><span class="line">    <span class="built_in">glClear</span>(GL_COLOR_BUFFER_BIT);<span class="comment">//清除颜色缓冲之后</span></span><br><span class="line"></span><br><span class="line">    </span><br><span class="line">    <span class="built_in">glUseProgram</span>(shaderProgram);<span class="comment">//调用着色器</span></span><br><span class="line">    <span class="built_in">glBindVertexArray</span>(VAO);</span><br><span class="line">    <span class="comment">//glDrawArrays(GL_TRIANGLES, 0, 3);</span></span><br><span class="line">    <span class="built_in">glBindVertexArray</span>(EBO);</span><br><span class="line">    <span class="built_in">glDrawElements</span>(GL_TRIANGLES, <span class="number">6</span>, GL_UNSIGNED_INT, <span class="number">0</span>);</span><br><span class="line">    <span class="built_in">glBindVertexArray</span>(<span class="number">0</span>);<span class="comment">//这是vao没有的</span></span><br><span class="line">    <span class="comment">//检查并调用事件，交换缓冲</span></span><br><span class="line">    <span class="built_in">glfwSwapBuffers</span>(window);<span class="comment">//进行屏幕缓冲</span></span><br><span class="line">    <span class="built_in">glfwPollEvents</span>();<span class="comment">//检查函数有没有触发事件</span></span><br><span class="line"></span><br><span class="line">  &#125;</span><br><span class="line">  <span class="built_in">glfwTerminate</span>();</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">framebuffer_size_callback</span><span class="params">(GLFWwindow* window, <span class="type">int</span> width, <span class="type">int</span> height)</span></span>&#123;</span><br><span class="line">  <span class="built_in">glViewport</span>(<span class="number">0</span>, <span class="number">0</span>, width, height);</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">processInput</span><span class="params">(GLFWwindow* window)</span> </span>&#123;</span><br><span class="line">  <span class="comment">//输入</span></span><br><span class="line">  <span class="keyword">if</span> (<span class="built_in">glfwGetKey</span>(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) &#123;</span><br><span class="line">    <span class="built_in">glfwSetWindowShouldClose</span>(window, GLFW_TRUE);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">CheckCompileShaderSuccess</span><span class="params">(<span class="type">unsigned</span> <span class="type">int</span> vertexShader)</span> </span>&#123;</span><br><span class="line">  <span class="comment">//检查着色器是否编译成功</span></span><br><span class="line">  <span class="type">int</span> success;</span><br><span class="line">  <span class="type">char</span> infoLog[<span class="number">512</span>];</span><br><span class="line">  <span class="built_in">glGetShaderiv</span>(vertexShader, GL_COMPILE_STATUS, &amp;success);</span><br><span class="line">  <span class="keyword">if</span> (!success) &#123;</span><br><span class="line">    <span class="built_in">glGetShaderInfoLog</span>(vertexShader, <span class="number">512</span>, <span class="literal">NULL</span>, infoLog);</span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;ERROR::SHADER::VERTEX::COMPILATION_FAILED\n&quot;</span> &lt;&lt; infoLog &lt;&lt; std::endl;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">CheckLinkShaderSuccess</span><span class="params">(<span class="type">unsigned</span> <span class="type">int</span> shaderProgram)</span> </span>&#123;</span><br><span class="line">  <span class="comment">//检查shaderProgram连接成功</span></span><br><span class="line">  <span class="type">int</span> success;</span><br><span class="line">  <span class="type">char</span> infoLog[<span class="number">512</span>];</span><br><span class="line">  <span class="built_in">glGetProgramiv</span>(shaderProgram, GL_LINK_STATUS, &amp;success);</span><br><span class="line">  <span class="keyword">if</span> (!success) &#123;</span><br><span class="line">    <span class="built_in">glGetProgramInfoLog</span>(shaderProgram, <span class="number">512</span>, <span class="literal">NULL</span>, infoLog);</span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;ERROR::SHADER::Program::Link_FAILED\n&quot;</span> &lt;&lt; infoLog &lt;&lt; std::endl;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
            <!--[if lt IE 9]><script>document.createElement('audio');</script><![endif]-->
            <audio id="audio" loop="1" preload="auto" controls="controls" data-autoplay="false">
                <source type="audio/mpeg" src="/music/jucilang.mp3">
            </audio>
            
        </div>
        
    <div id='gitalk-container' class="comment link"
		data-enable='true'
        data-ae='true'
        data-ci='99f95a936c6fcdb1bd67'
        data-cs='c2d1bba3d6b7f9ade4f3de09a63925bd837c25ea'
        data-r='mrchenlearnspace.github.io'
        data-o='MrChenLearnSpace'
        data-a='MrChenLearnSpace'
        data-d='false'
    >查看评论</div>


    </div>
    
        <div class='side'>
			<ol class="toc"><li class="toc-item toc-level-3"><a class="toc-link" href="#VAO"><span class="toc-number">1.</span> <span class="toc-text">VAO</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#VBO"><span class="toc-number">2.</span> <span class="toc-text">VBO</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#shader"><span class="toc-number">3.</span> <span class="toc-text">shader</span></a></li></ol>	
        </div>
    
</div>


    </div>
</div>
</body>

<script src="//cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.min.js"></script>


<script src="//lib.baomitu.com/jquery/1.8.3/jquery.min.js"></script>
<script src="/blog/js/plugin.js"></script>
<script src="/blog/js/typed.js"></script>
<script src="/blog/js/diaspora.js"></script>


<link rel="stylesheet" href="/blog/photoswipe/photoswipe.css">
<link rel="stylesheet" href="/blog/photoswipe/default-skin/default-skin.css">


<script src="/blog/photoswipe/photoswipe.min.js"></script>
<script src="/blog/photoswipe/photoswipe-ui-default.min.js"></script>


<!-- Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">
    <!-- Background of PhotoSwipe. 
         It's a separate element as animating opacity is faster than rgba(). -->
    <div class="pswp__bg"></div>
    <!-- Slides wrapper with overflow:hidden. -->
    <div class="pswp__scroll-wrap">
        <!-- Container that holds slides. 
            PhotoSwipe keeps only 3 of them in the DOM to save memory.
            Don't modify these 3 pswp__item elements, data is added later on. -->
        <div class="pswp__container">
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
        </div>
        <!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
        <div class="pswp__ui pswp__ui--hidden">
            <div class="pswp__top-bar">
                <!--  Controls are self-explanatory. Order can be changed. -->
                <div class="pswp__counter"></div>
                <button class="pswp__button pswp__button--close" title="Close (Esc)"></button>
                <button class="pswp__button pswp__button--share" title="Share"></button>
                <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>
                <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>
                <!-- Preloader demo http://codepen.io/dimsemenov/pen/yyBWoR -->
                <!-- element will get class pswp__preloader--active when preloader is running -->
                <div class="pswp__preloader">
                    <div class="pswp__preloader__icn">
                      <div class="pswp__preloader__cut">
                        <div class="pswp__preloader__donut"></div>
                      </div>
                    </div>
                </div>
            </div>
            <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
                <div class="pswp__share-tooltip"></div> 
            </div>
            <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
            </button>
            <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
            </button>
            <div class="pswp__caption">
                <div class="pswp__caption__center"></div>
            </div>
        </div>
    </div>
</div>



<script type="text/x-mathjax-config">
    MathJax.Hub.Config({"HTML-CSS": { preferredFont: "TeX", availableFonts: ["STIX","TeX"], linebreaks: { automatic:true }, EqnChunk: (MathJax.Hub.Browser.isMobile ? 10 : 50) },
        tex2jax: { inlineMath: [ ["$", "$"], ["\\(","\\)"] ], processEscapes: true, ignoreClass: "tex2jax_ignore|dno",skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']},
        TeX: {  noUndefined: { attributes: { mathcolor: "red", mathbackground: "#FFEEEE", mathsize: "90%" } }, Macros: { href: "{}" } },
        messageStyle: "none"
    });
</script>
<script type="text/x-mathjax-config">
    MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax(), i;
        for(i=0; i < all.length; i += 1) {
            all[i].SourceElement().parentNode.className += ' has-jax';
        }
    });
</script>

<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>



<!-- Google Analytics -->
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-YMJ8CBH8F7"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'G-YMJ8CBH8F7');
</script>
<!-- End Google Analytics -->


</html>
